package com.in.filter;


import com.in.entity.CustomerUserDetails;
import com.in.utils.CommonConstant;
import com.in.utils.JwtUtil;
import com.in.utils.RedisUtil;
import jakarta.annotation.Resource;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;
import java.io.PrintWriter;


/**
 * @ClassName JwtFilter
 * @Description 过滤器
 * @Author liulianjia
 * @Date 2023/6/1 14:13
 */
@Component
public class JwtFilter extends OncePerRequestFilter {

    @Resource
    private RedisUtil redisUtil;

    @Override
    protected void doFilterInternal(HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull FilterChain filterChain) throws ServletException, IOException {
        String token = request.getHeader(CommonConstant.ACCESS_TOKEN);
        // 没有token，去走登录流程
        if (StringUtils.isBlank(token)) {
            filterChain.doFilter(request, response);
            return;
        }
        //校验token是否有效
        if (!redisUtil.hasKey(CommonConstant.PREFIX_USER_TOKEN + JwtUtil.getAccount(token) + token)) {
            response.setStatus(401);
            returnJson("无效的token!", response);
            throw new ServletException("无效的token!");
        }
        CustomerUserDetails loginUser = (CustomerUserDetails) redisUtil.get(token);
        // 如果用户不存在，说明token异常
        if (loginUser == null) {
            response.setStatus(401);
            returnJson("token异常!", response);
            throw new NullPointerException("token异常!");
        }

        // 将用户信息存入 SecurityContextHolder ，以便本次在请求中使用
        UsernamePasswordAuthenticationToken authenticationLoginUser = new UsernamePasswordAuthenticationToken(null, null, null);
        SecurityContextHolder.getContext().setAuthentication(authenticationLoginUser);

        filterChain.doFilter(request, response);
    }

    private void returnJson(String json, HttpServletResponse response) {
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html; charset=utf-8");
        try (PrintWriter writer = response.getWriter()) {
            writer.print(json);
        } catch (IOException ignored) {

        }
    }
}
